#include <iostream>
#include <csignal>
#include <filesystem>
#include <fstream>
#include "workflow/WFHttpServer.h"
#include "workflow/WFFacilities.h"
#include "handlers/http_handler.hpp"
#include "common/config.hpp"
#include "database/db_connection.hpp"
#include "utils/file_utils.hpp"
#include "utils/oss_client_manager.hpp"


static WFFacilities::WaitGroup g_wait_group(1);

void sig_handler(int signum) {
    g_wait_group.done();
}

// 辅助函数：根据文件后缀名获取 Content-Type
static std::string get_content_type(const std::string& path) {
    std::string ext = std::filesystem::path(path).extension().string();
    if (ext == ".html" || ext == ".htm") return "text/html; charset=utf-8";
    if (ext == ".css") return "text/css";
    if (ext == ".js") return "application/javascript";
    if (ext == ".png") return "image/png";
    if (ext == ".jpg" || ext == ".jpeg") return "image/jpeg";
    if (ext == ".ico") return "image/x-icon";
    return "application/octet-stream";
}

void process(WFHttpTask* task) {
    std::string path_with_query = task->get_req()->get_request_uri();
    const std::string& method = task->get_req()->get_method();

    std::string path = path_with_query;
    size_t query_pos = path_with_query.find('?');
    if (query_pos != std::string::npos) {
        path = path_with_query.substr(0, query_pos);
    }

    // --- 1. 优先、清晰地处理所有 API 路由 ---
    if (path.rfind("/user/", 0) == 0 || path.rfind("/file/", 0) == 0) {
        if (method == "POST") {
            if (path == "/user/signup") { return HttpHandlers::handleSignup(task); }
            if (path == "/user/signin") { return HttpHandlers::handleSignin(task); }
            if (path == "/file/query") { return HttpHandlers::handleQuery(task); }
            if (path == "/file/upload") { return HttpHandlers::handleUpload(task); } // <--- 现在可以正确匹配了
            if (path == "/file/delete") { return HttpHandlers::handleDelete(task); }
        } else if (method == "GET") {
            if (path == "/user/info") { return HttpHandlers::handleGetUserInfo(task); }
            if (path.rfind("/file/download/", 0) == 0) { return HttpHandlers::handleDownload(task); }
        }
        // 如果是 API 路径但未匹配到任何具体处理函数，则返回 404
        HttpHandlers::handleNotFound(task);
        return;
    }

    // --- 2. 如果不是 API 请求，再处理静态文件请求 ---
    if (method == "GET") {
        std::string file_path;
        if (path == "/") {
            file_path = "./static/view/signin.html";
        } else {
            file_path = "." + path;
        }

        std::filesystem::path static_root = std::filesystem::weakly_canonical("./static");
        std::filesystem::path canonical_path = std::filesystem::weakly_canonical(file_path);

        if (canonical_path.string().rfind(static_root.string(), 0) == 0 && FileUtils::fileExists(canonical_path.string())) {
            long long file_size = FileUtils::getFileSize(canonical_path.string());
            if (file_size >= 0) {
                char* buf = new char[file_size];
                auto* pread_task = WFTaskFactory::create_pread_task(canonical_path.string(), buf, file_size, 0,
                [task, buf, file_size, file_path](WFFileIOTask *t) {
                    if (t->get_retval() == file_size) {
                        task->get_resp()->append_output_body(buf, file_size);
                        task->get_resp()->add_header_pair("Content-Type", get_content_type(file_path));
                    } else {
                        task->get_resp()->set_status_code("500");
                    }
                    delete[] buf;
                });
                series_of(task)->push_back(pread_task);
                return;
            }
        }
    }

    // --- 3. 所有其他情况，都视为 404 Not Found ---
    HttpHandlers::handleNotFound(task);
}

int main(int argc, char *argv[]) {
    // ... main 函数的其他内容保持不变 ...
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);
    
    if (!Config::load()) {
        fprintf(stderr, "Error: Failed to load config/app.conf\n");
        return 1;
    }

    if (!DBConnection::getInstance()->connect()) {
        fprintf(stderr, "Error: Failed to connect to database\n");
        return 1;
    }

    // 初始化OSS客户端
    OssClientManager::getInstance()->init();


    WFHttpServer server(process);
    if (server.start(Config::SERVER_PORT) == 0) {
        fprintf(stderr, "Server started on http://localhost:%d\n", Config::SERVER_PORT);
        g_wait_group.wait();
        server.stop();
    } else {
        perror("Cannot start server");
        return 1;
    }

    return 0;
}
